package com.chinaedu.oc.filter.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.chinaedu.oc.context.Common.Session;
import com.chinaedu.oc.dao.manageauthority.ManageAuthorityDao;
import com.chinaedu.oc.dao.managegroup.ManageGroupDao;
import com.chinaedu.oc.dao.membership.MemberShipDao;
import com.chinaedu.oc.entity.authority.ManageAuthority;
import com.chinaedu.oc.entity.manageuser.ManageUser;
import com.chinaedu.oc.service.manageuser.ManageUserLoginService;
import com.chinaedu.oc.utils.JsonMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;


@Component
public class ManageUserLoginFilter implements Filter, ApplicationContextAware {
	private static ManageUserLoginService manageUserLoginService;
	private Predicate<String> excludePath;// 排除验证用户登录的路径
	private MemberShipDao memberShipDao;
	private ManageGroupDao manageGroupDao;
	private ManageAuthorityDao manageAuthorityDao;
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		manageUserLoginService = applicationContext.getBean(ManageUserLoginService.class);
		memberShipDao = applicationContext.getBean(MemberShipDao.class);
		manageGroupDao = applicationContext.getBean(ManageGroupDao.class);
		manageAuthorityDao = applicationContext.getBean(ManageAuthorityDao.class);
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {
		String exclude = fConfig.getInitParameter("exclude");
		excludePath = Pattern.compile(exclude).asPredicate();
		excludePath.test("");// 验证正则表达式是否正确
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		response.setCharacterEncoding("utf-8");//解决中文乱码
		PrintWriter out = response.getWriter(); 
		Map<String, Object> result = Maps.newHashMap();
		String uri = request.getRequestURI();
		String projectName= request.getContextPath();
		if(!projectName.equals("")){
			uri=uri.replace(projectName,"");
		}
		
		if (excludePath.test(uri)) {
			chain.doFilter(req, res);
			return;
		} else {
				//判断是否登录
				if (manageUserLoginService.validateManageUserLogin(request).isPresent()) {
					//获取当前用户所拥有的权限-------start-------------
					HttpSession session = request.getSession();
					ManageUser manageUser = (ManageUser) session.getAttribute(Session.manageUserLogin.name());
					String groupId = memberShipDao.findGroupIdByUserId(Objects.nonNull(manageUser) ? manageUser.getUserId() : "0");
					//根据用户组id获取该角色的权限值   还是应该从session中取？？？？？？？？？？
					String authvalue = manageGroupDao.findAuthValueByGroupId(groupId);
					List<ManageAuthority> selectedAuthorities = Lists.newArrayList();//当前角色已勾选的权限
					if(authvalue!=null && !"-1".equals(authvalue)){
						List<ManageAuthority> authorities = manageAuthorityDao.getAuthList();//获取所有权限链接
						selectedAuthorities = authorities.stream()
								.filter(a -> (a != null && ((new BigInteger(a.getAuthValue()).and(new BigInteger(authvalue))).compareTo(new BigInteger(a.getAuthValue())) == 0)))
								.collect(Collectors.toList());
						//--------------end---------------
						
						//这个地方不能用contains  因为url获取到的还会有参数和虚拟目录
						String uriNew=uri.split("\\?")[0];
						// 验证是否有访问链接的权限,如果uri不在authorities中则放过，如果在 那再判断是否在allowMenuUrls中，在则过
						if (authorities.contains(uriNew)) {
							if (selectedAuthorities != null && !selectedAuthorities.contains(uriNew)) {
								
								result.put("success", false);
								result.put("msg", "您没有权限！");
								out.print(JsonMapper.toJsonString(result));
								return ;
							}
						}
					
					}else{
						//为-1 则放过  是超级管理员
						chain.doFilter(req, res);
						return;
					}
					
				}else{
					//没有登录
					result.put("success", false);
					result.put("msg", "您还未登录！");
					out.print(JsonMapper.toJsonString(result));
					return ;
				}
		}

	}
	
	@Override
	public void destroy() {
	}

}
